package com.google.code.synchronized_player;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class MainActivity extends Activity {
	ListView playListView;
	PlayList playList;
	PlayListAdapter playListAdapter;
	SeekBar progress;
	SurfaceView display;
	Button playButton;
	Controller controller;
	Player player;
	boolean running = true;
	
	public class Player implements Runnable, OnCompletionListener, OnPreparedListener {
		MediaPlayer mediaPlayer = new MediaPlayer();
		boolean isPlaying = false;
		Thread progressUpdate;
		
		public Player() {
			mediaPlayer.setOnCompletionListener(this);
			initTrack();
			progress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

				@Override
				public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
					if (fromUser) {
			            mediaPlayer.seekTo(progress);
			        }
				}

				@Override
				public void onStartTrackingTouch(SeekBar seekBar) {
				}

				@Override
				public void onStopTrackingTouch(SeekBar seekBar) {
				}
			});
		}
		
		public void setTrack(int position) {
			playList.setCurrentTrackNumber(position);
			playList.setTrackPosition(0);
			initTrack();
		}
		
		public void playPause() {
			playListView.setVisibility(View.VISIBLE);
			display.setVisibility(View.GONE);
			if(isPlaying) {
				playButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.play));
				mediaPlayer.pause();
				if(progressUpdate != null) {
					progressUpdate.interrupt();
					progressUpdate = null;
				}
			} else {
				playButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.pause));
				Log.d("MA", Integer.toString(mediaPlayer.getVideoWidth()));
				if(mediaPlayer.getVideoWidth() > 0) {
					Log.d("MA", "Is Video");
					playListView.setVisibility(View.GONE);
					display.setVisibility(View.VISIBLE);
					SurfaceHolder surfaceHolder = display.getHolder();
					mediaPlayer.setDisplay(surfaceHolder);
					surfaceHolder.setFixedSize(176, 144);
					surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

				}
				mediaPlayer.start();
				progressUpdate = new Thread(this);
				progressUpdate.start();
			}
			isPlaying = (!isPlaying);
		}
		
		public void prevTrack() {
			if(playList.prevTrack()) {
				initTrack();
			}
		}
		
		public void nextTrack() {
			if(playList.nextTrack()) {
				initTrack();
			}
		}
		
		public void initTrack() {
			runOnUiThread(new Runnable() {
				public void run() {
					if(progressUpdate != null) {
						progressUpdate.interrupt();
						progressUpdate = null;
					}
					if(playList == null)
						return;
					if(isPlaying) {
						playPause();
					}
					try {
						mediaPlayer.reset();
						Log.d("Player", "Playing: " + String.valueOf(playList.getCurrentTrackNumber()) + ": " + String.valueOf(playList.getTrackPosition()));
						Track currentTrack = playList.getCurrentTrack();
						if(currentTrack == null)
							return;
						mediaPlayer.setDataSource(currentTrack.getPath());
			            mediaPlayer.prepare();
			            mediaPlayer.setOnPreparedListener(Player.this);
					} catch(IOException ex) {
						Log.d("MA", ex.getMessage());
						if(!playList.nextTrack()) {
							playList.setCurrentTrackNumber(0);
						}
						initTrack();
						return;
					}
					progress.setProgress(0);
					playListAdapter.notifyDataSetChanged();
				}
			});
		}
		
		public void setItem(int position) {
			int first = playListView.getFirstVisiblePosition();
			int last = playListView.getFirstVisiblePosition() + playListView.getLastVisiblePosition();
			for(int i = 0; i < playListView.getChildCount(); ++i) {
				View currentView = playListView.getChildAt(i);
				currentView.setBackgroundDrawable(null);
				((TextView)currentView.findViewById(R.id.track_name)).setTextColor(Color.parseColor("#DDDDDD"));
			}
			if(first <= position && position <= last) {
				View currentView = playListView.getChildAt(position - first);
				currentView.setBackgroundDrawable(getResources().getDrawable(R.drawable.select));
				((TextView)currentView.findViewById(R.id.track_name)).setTextColor(Color.parseColor("#FFFFFF"));
			}
		}
		
		@Override
		public void run() {
	        while (running && mediaPlayer != null && isPlaying) {
	        	try {
	        		int currentPosition = 0;
	        		int total = mediaPlayer.getDuration();
	        		currentPosition = mediaPlayer.getCurrentPosition();
	        		progress.setMax(total);
	        		progress.setProgress(currentPosition);
	        		playList.setTrackPosition(mediaPlayer.getCurrentPosition());
	        		runOnUiThread(new Runnable() {
	        			public void run() {
	        				 setItem(playList.getCurrentTrackNumber());
	        			}
	        		});
	        		Thread.sleep(1000);
		        } catch (InterruptedException e) {
		            return;
		        } catch (Exception e) {
		            return;
		        }    
	        }
		}

		@Override
		public void onCompletion(MediaPlayer mp) {
			Log.d("Player", "Complete");
			if(playList.nextTrack()) {
				initTrack();
			}
		}

		public void onPrepared(MediaPlayer mediaplayer) {
			 if(!isPlaying) {
				mediaPlayer.seekTo(playList.getTrackPosition());
             	progress.setMax(mediaPlayer.getDuration());
             	playPause();
			 }
	    }
	}
	
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        playListView = (ListView)this.findViewById(R.id.playlist);
        display = (SurfaceView)this.findViewById(R.id.video_diplay);
        playButton = (Button)this.findViewById(R.id.play_pause_button);
        progress = (SeekBar)this.findViewById(R.id.progress);
        player = new Player();
        playList = new PlayList(this.getApplicationContext(), player);
        playListAdapter = new PlayListAdapter(this, playList.getTracksList());
        playListView.setAdapter(playListAdapter);
        bind_playlist();
        initSettings();
    }
    
    public void initSettings() {
    	try {
        	SharedPreferences sharedPreferences = getSharedPreferences("network", MODE_WORLD_READABLE);
        	String ip = sharedPreferences.getString("IP", "");
        	int port = sharedPreferences.getInt("port", 0);
        	int listenPort = sharedPreferences.getInt("listenPort", 0); 
        	Log.d("MainActivity", ip + ":" + String.valueOf(port) + " listenPort: " + String.valueOf(listenPort));
        	if(listenPort > 0 && !ip.equals("") && port > 0) {
        		controller = new Controller(listenPort, ip, port, playList);
        	}
        	playList.addSourceFolder(sharedPreferences.getString("SourceDirectory", "/"));
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.layout.main_menu, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.add_to_play_list:
        	startActivityForResult(new Intent(this.getApplicationContext(), SelectorActivity.class), 1);
            return true;
        case R.id.rem_from_play_list:
        	Track removedTrack = playList.getCurrentTrack();
        	playList.removeTrack(removedTrack.getPath());
        	playList.setTrackPosition(0);
	    	playListAdapter.notifyDataSetChanged();
	    	player.initTrack();
        	return true;
        case R.id.save_play_list:
        	startActivityForResult(new Intent(this.getApplicationContext(), SelectorActivity.class), 2);
        	return true;
        case R.id.settings:
        	startActivityForResult(new Intent(this.getApplicationContext(), SettingsActivity.class), 3);
            return true;
        case R.id.synchronize:
        	if(playList == null)
        		return true;
        	ArrayList<Track> tracks = playList.getTracksList();
        	String strings[] = new String[tracks.size()];
        	int index = 0;
        	for(Track currentTrack: tracks) {
        		strings[index++] = currentTrack.getHash();
        	}
        	controller.SendPlaylist(String.valueOf(playList.getCurrentTrackNumber()), String.valueOf((int)(0.001 * playList.getTrackPosition())), strings);
        	return true;
        case R.id.exit:
        	finish();
        	return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    	String s = data.getStringExtra("path");
    	switch(requestCode) {
    	case 1:
	    	if(!s.equals("") && (new File(s)).isFile()) { 
	    		Log.d("MA", "addTrack" + s);
		    	playList.addTrack(s);
		    	playListAdapter.notifyDataSetChanged();
		    	bind_playlist();
	    	}
	    	break;
    	case 2:
    		if(!s.equals("") && (new File(s)).isDirectory()) {
    			playList.writePlayList(s + "/playlist.m3u");
    		}
    		break;
    	case 3:
    		if(controller != null && controller.thread != null) {
    			controller.thread.interrupt();
    		}
    		initSettings();
    	}
    }
    
    public void bind_playlist() {
    	playListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				player.setTrack(position);
			}
        });
    }
    
    public void finish() {
    	if(player.mediaPlayer != null) {
    		player.mediaPlayer.reset();
    	}
    	if(controller != null && controller.thread != null) {
    		controller.thread.interrupt();
    	}
    	running = false;
    	super.finish();
    }
    
    public void onPlayPauseClick(View v) {
    	player.playPause();
    }
    
    public void onBackwardButtonClick(View v) {
    	player.prevTrack();
    }
    
    public void onForwardButtonClick(View v) {
    	player.nextTrack();
    }
}